package jvs.vfs.tools;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import x.java.io.File;

/**
 * 
 * @author Eric Armstrong, Tom Santos, and Steve Wilson
 * 
 */
public class FileExplorer extends JPanel {

	private static final long serialVersionUID = 1L;

	protected StatusBar statusbar = null;

	protected JToolBar toolbar = null;

	protected JTree tree;

	public FileExplorer() {
		//
		FileSystemModel model = new FileSystemModel();
		DirectoryModel directoryModel = new DirectoryModel((File) model
				.getRoot());
		JTable table = new JTable(directoryModel);
		table.setShowHorizontalLines(false);
		table.setShowVerticalLines(false);
		table.setIntercellSpacing(new Dimension(0, 2));
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.getColumn("Type").setCellRenderer(new DirectoryRenderer());
		table.getColumn("Type").setMaxWidth(32);
		table.getColumn("Type").setMinWidth(32);

		FileSystemTreePanel fileTree = new FileSystemTreePanel(this, model);
		tree = fileTree.getTree();
		tree.addTreeSelectionListener(new TreeListener(directoryModel));
		model.addTreeModelListener(new ModelListener(directoryModel));

		JScrollPane treeScroller = new JScrollPane(fileTree);
		// JScrollPane tableScroller = JTable.createScrollPaneForTable( table );
		JScrollPane tableScroller = new JScrollPane(table);

		treeScroller.setMinimumSize(new Dimension(0, 0));
		treeScroller.setPreferredSize(new Dimension(200, 400));
		tableScroller.setMinimumSize(new Dimension(0, 0));
		tableScroller.setBackground(Color.white);
		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				treeScroller, tableScroller);
		splitPane.setContinuousLayout(true);
		splitPane.setDividerSize(3);
		splitPane.setDividerLocation(200);

		setLayout(new BorderLayout());

		toolbar = createToolbar();
		toolbar.setFloatable(false);
		toolbar.setPreferredSize(new Dimension(200, 20));
		statusbar = createStatusbar();
		statusbar.setPreferredSize(new Dimension(200, 20));

		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.add("North", toolbar);
		panel.add("Center", splitPane);
		add("Center", panel);
		add("South", statusbar);
	}

	protected JMenuBar createMenubar() {
		return new JMenuBar();
	}

	private JToolBar createToolbar() {
		JToolBar tb = new JToolBar();
		return tb;
	}

	protected StatusBar createStatusbar() {
		return new StatusBar();
	}

	public static void ve(java.io.File file) {
		try {
			// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			UIManager.setLookAndFeel(UIManager
					.getCrossPlatformLookAndFeelClassName());

			final JFrame frame = new JFrame("VFS Explorer");
			frame.addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					frame.dispose();
				}
			});
			FileExplorer fe = new FileExplorer();

			fe.setSelectedFile((x.java.io.File) file);

			frame.getContentPane().add(fe);

			frame.setSize(700, 500);

			Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
			frame.setLocation((d.width - frame.getSize().width) / 2,
					(d.height - frame.getSize().height) / 2);

			frame.setVisible(true);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		if (args.length > 0) {
			ve(new File(args[0]));
		} else {
			ve(null);
		}
	}

	public File getSelectedFile() {
		TreePath path = tree.getSelectionPath();
		if (path != null) {
			return (File) path.getLastPathComponent();
		}
		return null;
	}

	public void setSelectedFile(File file) {
		if (file == null) {
			return;
		}

		File p = file;
		ArrayList<File> al = new ArrayList<File>();
		do {
			al.add(0, p);
		} while ((p = (File) p.getParentFile()) != null);
		TreePath path = new TreePath(al.toArray(new File[0]));
		//
		tree.setSelectionPath(path);
		tree.scrollPathToVisible(path);
	}

	protected static class TreeListener implements TreeSelectionListener {
		DirectoryModel model;

		public TreeListener(DirectoryModel mdl) {
			model = mdl;
		}

		public void valueChanged(TreeSelectionEvent e) {
			File fileSysEntity = (File) e.getPath().getLastPathComponent();

			if (fileSysEntity.isDirectory()) {
				model.setDirectory(fileSysEntity);
			} else {
				model.setDirectory(null);
			}
		}
	}

	protected static class ModelListener implements TreeModelListener {

		private DirectoryModel model;

		public ModelListener(DirectoryModel model) {
			this.model = model;
		}

		public void treeNodesChanged(TreeModelEvent e) {
		}

		public void treeNodesInserted(TreeModelEvent e) {
		}

		public void treeNodesRemoved(TreeModelEvent e) {
		}

		public void treeStructureChanged(TreeModelEvent e) {
			model.setDirectory(null);
		}

	}
}
